package it.gestionedocumentale.hibernate.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import it.gestionedocumentale.model.Profilo;
import it.gestionedocumentale.model.Utente;

public class UtenteDAO extends BaseHibernateDAO {
	
	// property constants
	public static final String LOGIN = "login";
	public static final String PASSWORD = "password";
	public static final String ATTIVO = "attivo";

	public void save(Utente transientInstance) throws Exception{
		getSession().save(transientInstance);
	}
	
	public void update(Utente transientInstance) throws Exception{
		getSession().saveOrUpdate(transientInstance);
	}

	public void delete(Utente persistentInstance) throws Exception{
		getSession().delete(persistentInstance);
	}

	public Utente findById(Long id) throws Exception{
		Utente instance = (Utente) getSession().get(Utente.class, id);
		return instance;
	}

	@SuppressWarnings("unchecked")
	public List<Utente> findByExample(Utente instance) throws Exception{
		Criteria cri = getSession().createCriteria(Utente.class);
		cri.add(Example.create(instance));
		if (instance.getProfilo() != null) {
			cri.add(Restrictions.eq("profilo", instance.getProfilo()));
		}
		if (instance.getGruppo() != null) {
			cri.add(Restrictions.eq("gruppo", instance.getGruppo()));
		}
		List<Utente> results = cri.list();
		return results;
	}
	
	@SuppressWarnings("unchecked")
	public List<Utente> searchUtente(Utente utente, Profilo profilo) throws Exception{
		
		Criteria cri = getSession().createCriteria(Utente.class);
//		cri.add(Example.create(utente));
		
		if(utente.getLogin()!=null) {
			cri.add(Restrictions.ilike(LOGIN, utente.getLogin(), MatchMode.ANYWHERE));
		}
		if(utente.getAttivo()!=null){
			cri.add(Restrictions.eq("attivo", utente.getAttivo()));
		}
		if (utente.getGruppo() != null) {
			cri.add(Restrictions.eq("gruppo", utente.getGruppo()));
		}
		cri.createAlias("profilo", "p");
		if (profilo.getNome()!=null){
			cri.add(Restrictions.ilike("p.nome", profilo.getNome(), MatchMode.ANYWHERE));
		}
		if (profilo.getCognome()!=null){
			cri.add(Restrictions.ilike("p.cognome", profilo.getCognome(), MatchMode.ANYWHERE));
		}
		if (profilo.getEmail()!=null){
			cri.add(Restrictions.ilike("p.email", profilo.getEmail(), MatchMode.ANYWHERE));
		}
		List<Utente> results = cri.list();
		return results;
	}
	
	@SuppressWarnings("unchecked")
	public List<Utente> controllaLogin(Utente utente) throws Exception {
		Criteria cri = getSession().createCriteria(Utente.class);
		cri.add(Restrictions.eq(LOGIN, utente.getLogin()));
		cri.add(Restrictions.not(Restrictions.eq("idUtente", utente.getIdUtente())));
		return cri.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Utente> findAll() throws Exception{
		String queryString = "from Utente";
		Query queryObject = getSession().createQuery(queryString);
		return queryObject.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Utente> findByProperty(String propertyName, Object value) throws Exception{
		String queryString = "from Utente as model where model." + propertyName
				+ "= ?";
		Query queryObject = getSession().createQuery(queryString);
		queryObject.setParameter(0, value);
		return queryObject.list();
	}
	
	public List<Utente> findByLogin(Object login) throws Exception{
		return findByProperty(LOGIN, login);
	}
	
	public List<Utente> findByPassword(Object password) throws Exception{
		return findByProperty(PASSWORD, password);
	}
	
	public List<Utente> findByAttivo(Object attivo) throws Exception{
		return findByProperty(ATTIVO, attivo);
	}

	/*
	 * metodo utilizzato nella action di login
	 * cerca se c'e' un user attivo con la login e la password specificate
	 */
	public Utente findByLoginAndPassword(String login, String password) throws Exception{
		Criteria cri = getSession().createCriteria(Utente.class);
		cri.add(Restrictions.eq(LOGIN, login));
		cri.add(Restrictions.eq(PASSWORD, password));
		cri.add(Restrictions.eq(ATTIVO, "SI"));
		Utente result = (Utente) cri.uniqueResult();
		return result;
	}
	

	public Utente merge(Utente detachedInstance) throws Exception{
		Utente result = (Utente) getSession().merge(detachedInstance);
		return result;
	}

}
